/** @file

Copyright (c) 2006-2023, Kunlun BIOS, Kunlun Technology (Beijing) Co., Ltd.. All
Rights Reserved.

You may not reproduce, distribute, publish, display, perform, modify, adapt,
transmit, broadcast, present, recite, release, license or otherwise exploit
any part of this publication in any form, by any means, without the prior
written permission of Kunlun Technology (Beijing) Co., Ltd..

**/

#ifndef SELF_DEBUG_COMMON_H__
#define SELF_DEBUG_COMMON_H__

#define DebugLine() do { \
  DEBUG((EFI_D_INFO, "[%a:%d]\n",  \
    __FUNCTION__, __LINE__ \
  )); \
} while(0)

#define AlignTo4k(addr) (((addr) % (4*1024)) ? (((addr) / (4*1024)) + 1) * (4*1024) : (addr))

#define ShowCurrentTime() do { \
  EFI_TIME EfiTime; \
  EFI_STATUS Status = gRT->GetTime(&EfiTime, NULL); \
  if (!EFI_ERROR(Status)) { \
    DEBUG((EFI_D_INFO, "[%a:%d] Time: %04d-%02d-%02d %02d:%02d:%02d.%09d\n",  \
      __FUNCTION__, __LINE__, \
      EfiTime.Year, EfiTime.Month, EfiTime.Day, \
      EfiTime.Hour, EfiTime.Minute, EfiTime.Second,  \
      EfiTime.Nanosecond \
    )); \
  } \
} while(0)

#define SelfIsPrint(ch) ((((char)ch) >= ' ' && ((char)ch) <= '~') ? 1 : 0)

#define ShowHexString(Header, Buf, Size) do { \
  DEBUG((EFI_D_INFO, "[+] %a: \n", Header)); \
  int ii = 0; \
  for (ii = 0; ii < Size; ii++) { \
    DEBUG((EFI_D_INFO, "%02x ", ((UINT8*)Buf)[ii] & 0x0ff)); \
    if (((ii % 16) == 15) && (ii != (Size-1))) { \
      DEBUG((EFI_D_INFO, "| ")); \
      int jj = 0; \
      for (jj = 0; jj < 16; jj++) { \
        if (SelfIsPrint(((UINT8*)Buf)[ii-15+jj] & 0x0ff)) { \
          DEBUG((EFI_D_INFO, "%c", ((UINT8*)Buf)[ii-15+jj] & 0x0ff)); \
        } else { \
          DEBUG((EFI_D_INFO, "%c", '.')); \
        } \
      } \
      DEBUG((EFI_D_INFO, "\n")); \
    } \
  } \
  DEBUG((EFI_D_INFO, "\n")); \
} while(0)


#define ShowDecString(Header, Buf, Size) do { \
  DEBUG((EFI_D_INFO, "[+] %a: \n", Header)); \
  for (int i = 0; i < Size; i++) { \
    DEBUG((EFI_D_INFO, "%d ", ((UINT8*)Buf)[i] & 0x0ff)); \
    if (((i % 16) == 15) && (i != (Size-1))) DEBUG((EFI_D_INFO, "\n")); \
  } \
  DEBUG((EFI_D_INFO, "\n")); \
} while(0)

#define ShowLongAsciiString(StrPtr, Len) do { \
  CHAR8 DebugBuf[200+2]; \
  DebugBuf[200] = 0; \
  DebugBuf[200+1] = 0; \
  DEBUG((EFI_D_INFO, "[+] ")); \
  for (int i = 0; i < (Len)/200; i++) { \
    CopyMem(DebugBuf, &((UINT8*)StrPtr)[i*200], 200); \
    DEBUG((EFI_D_INFO, "%a", DebugBuf)); \
  } \
  if ((Len)%200) DEBUG((EFI_D_INFO, "%a",  &((UINT8*)StrPtr)[((Len)/200)*200])); \
  DEBUG((EFI_D_INFO, "\n")); \
} while (0)

#endif
